package admin.auth.feishu.controller;


import admin.auth.feishu.properties.FeishuProperties;
import admin.common.domain.rsp.*;
import cn.hutool.core.util.StrUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;
import admin.auth.feishu.feign.FeishuFeignClient;
import admin.auth.feishu.model.req.AppAuth;
import admin.auth.feishu.model.req.CodeAuth;
import admin.common.constant.AuthConstant;
import admin.redis.service.RedisService;

import javax.annotation.PostConstruct;


@RestController
@Tag(name = "飞书优途Java项目接口")
@RequestMapping("/feishuJava")
public class FeishuJavaController {

    @Autowired
    private FeishuFeignClient feishuFeignClient;

    @Autowired
    private RedisService redisService;


    @Autowired
    private FeishuProperties feishuProperties;


    @PostConstruct
    public void init() {
        redisService.del(AuthConstant.FEISHU_TENANTACCESSTOKEN_PREFIX);
        redisService.del(AuthConstant.FEISHU_APPACCESSTOKEN_PREFIX);
        redisService.del(AuthConstant.TOKEN_SESSIONLIST_PREFIX);
        redisService.del(AuthConstant.TOKEN_BLACKLIST_PREFIX);
    }


    @Operation(summary = "自建应用获取 tenant_access_token")
    @GetMapping("tenantAccessToken")
    public String tenantAccessToken() throws Exception {
        String key = AuthConstant.FEISHU_TENANTACCESSTOKEN_PREFIX;

        String value =(String) redisService.get(key);
        if(StringUtils.isNotBlank(value)){
            return value;
        }

        AppAuth appAuth = AppAuth.builder().appId(feishuProperties.getApp().getAppId()).appSecret(feishuProperties.getApp().getAppSecret()).build();

        R tenantAccessTokenR = feishuFeignClient.tenantAccessToken(appAuth);
        if (tenantAccessTokenR == null) {
            throw new Exception("调用 飞书 tenantAccessToken 接口异常:无返回");
        }
        if (tenantAccessTokenR.getCode() != 0) {
            throw new Exception(String.format("调用 飞书 tenantAccessToken 接口异常:返回码 %s，异常信息 %s%s", tenantAccessTokenR.getCode(), tenantAccessTokenR.getMsg(), tenantAccessTokenR.getMessage()));
        }
        if (StrUtil.isEmpty(tenantAccessTokenR.getTenantAccessToken())) {
            throw new Exception("调用 飞书 tenantAccessToken 接口异常：无返回 tenantAccessToken");
        }

        int expire = tenantAccessTokenR.getExpire();
        redisService.set(key,tenantAccessTokenR.getTenantAccessToken(),expire);
        return tenantAccessTokenR.getTenantAccessToken();
    }

    @Cacheable(value = "appAccessToken", key = "'appAccessToken'")
    @Operation(summary = "自建应用获取 app_access_token")
    @GetMapping("appAccessToken")
    public String appAccessToken() throws Exception {
        String key = AuthConstant.FEISHU_APPACCESSTOKEN_PREFIX;

        String value =(String) redisService.get(key);
        if(StringUtils.isNotBlank(value)){
            return value;
        }

        AppAuth appAuth = AppAuth.builder().appId(feishuProperties.getApp().getAppId()).appSecret(feishuProperties.getApp().getAppSecret()).build();

        R appAccessTokenR = feishuFeignClient.appAccessToken(appAuth);
        if (appAccessTokenR == null) {
            throw new Exception("调用 飞书 appAccessToken 接口异常:无返回");
        }
        if (appAccessTokenR.getCode() != 0) {
            throw new Exception(String.format("调用 飞书 appAccessToken 接口异常:返回码 %s，异常信息 %s%s", appAccessTokenR.getCode(), appAccessTokenR.getMsg(), appAccessTokenR.getMessage()));
        }
        if (StrUtil.isEmpty(appAccessTokenR.getAppAccessToken())) {
            throw new Exception("调用 飞书 appAccessToken 接口异常：无返回 appAccessToken");
        }

        int expire = appAccessTokenR.getExpire();
        redisService.set(key,appAccessTokenR.getAppAccessToken(),expire);
        return appAccessTokenR.getAppAccessToken();


    }


    @Operation(summary = "获取 user_access_token:请求头Authorization:Bearer app_access_token，feign已配置RequestInterceptor会把头Authorization传递到RequestTemplate")
    @GetMapping("userAccessToken")
    public String userAccessToken(@RequestParam("code") String code) throws Exception {
        String key = new StringBuffer().append(AuthConstant.FEISHU_USERACCESSTOKEN_PREFIX).append(":").append(code).toString();
        String value =(String) redisService.get(key);
        if(StringUtils.isNotBlank(value)){
            return value;
        }

        String appAccessToken = appAccessToken();
        R<UserAccessTokenRsp> userAccessTokenRspR = feishuFeignClient.userAccessToken(CodeAuth.builder().code(code).grantType("authorization_code").build(), AuthConstant.JWT_TOKEN_PREFIX.concat(appAccessToken));
        if (userAccessTokenRspR == null) {
            throw new Exception("调用 飞书 userAccessToken 接口异常:无返回");
        }
        if (userAccessTokenRspR.getCode() != 0) {
            throw new Exception(String.format("调用 飞书 userAccessToken 接口异常:返回码 %s，异常信息 %s%s", userAccessTokenRspR.getCode(), userAccessTokenRspR.getMsg(), userAccessTokenRspR.getMessage()));
        }

        if (userAccessTokenRspR.getData() == null || StrUtil.isEmpty(userAccessTokenRspR.getData().getAccessToken())) {
            throw new Exception("调用 飞书 userAccessToken 接口异常：无返回 userAccessToken");
        }
        int expire = userAccessTokenRspR.getData().getExpiresIn();
        redisService.set(key,userAccessTokenRspR.getData().getAccessToken(),expire);
        return userAccessTokenRspR.getData().getAccessToken();
    }

    @Operation(summary = "获取登录用户信息:请求头Authorization:Bearer userAccessToken，feign已配置RequestInterceptor会把头Authorization传递到RequestTemplate")
    @GetMapping("userInfo")
    public R<UserInfoRsp> userInfo(@RequestHeader("Authorization") String authorization) {
        return feishuFeignClient.userInfo();
    }

    @Operation(summary = "获取单个用户信息:请求头Authorization:Bearer userAccessToken，feign已配置RequestInterceptor会把头Authorization传递到RequestTemplate,飞书open_id=飞书user_id")
    @GetMapping("users/{userId}")
    public R<UsersRsp> users(@PathVariable("userId") String userId, @RequestHeader("Authorization") String authorization) {
        return feishuFeignClient.users(userId,"open_department_id","open_id",authorization);
    }


    @Operation(summary = "批量获取员工花名册信息:请求头Authorization:Bearer tenantAccessToken，feign已配置RequestInterceptor会把头Authorization传递到RequestTemplate")
    @GetMapping("employees")
    public R<EmployeesRsp> employees(@RequestHeader("Authorization") String authorization, @RequestParam(value = "pageToken", required = false) String pageToken) {
        return feishuFeignClient.employees(new int[]{2}, "basic",pageToken, 100,authorization);
    }


}
